﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Vowei.Core;
using Vowei.Data;
using Vowei.Data.Helpers;
using Vowei.Core.Models;
using Vowei.Data.Models;

namespace vowei.test
{
    [TestClass()]
    public class HierarchyTableHelpersTest : TestBase
    {
        private Guid _msfProjectId;
        private Guid _msfMilestoneId;
        private Guid _msfSubMilestoneId;
        private Guid _scrumProjectId;
        private Guid _scrumSprintId;

        private string[,] _msTitles = new string[,] {
            {"Vision/Scope Approved",""},
            {"", "Core Team Organized" },
            {"", "Vision/Scope Drafted" },
            {"Project Plans Approved",""},
            {"", "Technology Validatoin"},
            {"", "Functional Specification Baselined"},
            {"", "Master Plan Baselined"},
            {"", "Master Schedule Baselined"},
            {"", "Development and Test Environment Set Up"},
            {"Scope Complete", "" },
            {"", "Proof of Concept Complete"},
            {"", "Internal Build n Complete, Internal build n+1 Complete"},
            {"Release Readiness Approved", ""},
            {"", "Bug Convergence" },
            {"", "Zero Bug Bounce" },
            {"", "Release Candidates" },
            {"", "Pre-Production Test Complete"},
            {"", "User Acceptance Testing Complete"},
            {"", "Pilot Complete"},
            {"Deployment Complete", ""},
            {"", "Core Components Deployed" },
            {"", "Site Deployments Complete Interim Milestone"},
            {"", "Deployment Stable Interim Miletone"}
        };

        private void CreateTestDatabase()
        {
            using (var impl = new VoweiContextImpl())
            {
                #region MSF项目类型
                var project = new Project()
                {
                    Title = "MSF Project",
                    Owner = Setting.DefaultUserName,
                    StartDate = DateTime.Now
                };
                impl.Projects.Add(project);
                impl.SaveChanges();

                _msfProjectId = project.ID;

                Milestone prevMajor = null;
                for (int i = 0; i < _msTitles.GetLength(0); ++i)
                {
                    var milestone = new Milestone()
                    {
                        DueDate = project.StartDate + TimeSpan.FromDays(30)
                    };
                    impl.Milestones.Add(milestone);

                    // 小里程碑 - Interim Milestone
                    if (string.IsNullOrEmpty(_msTitles[i, 0]))
                    {
                        milestone.Title = _msTitles[i, 1];

                        // 每次添加一个里程碑，都需要更新一下数据库，这是必须的
                        prevMajor.Children.Add(milestone);
                        impl.SaveChanges();
                        if (TableMeta.IsIdEmpty(_msfSubMilestoneId)) _msfSubMilestoneId = milestone.ID;
                    }
                    else
                    {
                        milestone.Title = _msTitles[i, 0];
                        prevMajor = milestone;

                        // 每次添加一个里程碑，都需要更新一下数据库，这是必须的
                        project.Children.Add(milestone);
                        impl.SaveChanges();
                        if (TableMeta.IsIdEmpty(_msfMilestoneId)) _msfMilestoneId = milestone.ID;
                    }
                }

                impl.SaveChanges();
                #endregion

                #region Scrum项目类型
                project = new Project()
                {
                    Title = "Scrum Project",
                    Owner = Setting.DefaultUserName,
                    StartDate = DateTime.Now
                };
                impl.Projects.Add(project);
                impl.SaveChanges();

                _scrumProjectId = project.ID;

                for (int i = 1; i < 13; ++i)
                {
                    var milestone = new Milestone()
                    {
                        Title = string.Format("Spring {0}", i),
                        DueDate = project.StartDate + TimeSpan.FromDays(30)
                    };
                    project.Children.Add(milestone);
                    impl.Milestones.Add(milestone);
                    impl.SaveChanges();

                    if (TableMeta.IsIdEmpty(_scrumSprintId)) _scrumSprintId = milestone.ID;
                }
                #endregion
            }
        }
        
        [TestMethod()]
        public void FullTreeTest()
        {
            // 测试MSF项目
            using (var impl = new VoweiContextImpl())
            {
                var expectedTitles = new List<string>();
                var context = new VoweiContext(impl);
                for (int i = 0; i < _msTitles.GetLength(0); ++i)
                {
                    var expectedTitle = _msTitles[i, 0];
                    if (string.IsNullOrEmpty(expectedTitle))
                        expectedTitle = _msTitles[i, 1];

                    expectedTitles.Add(expectedTitle);
                }

                var root = impl.Projects.First(p => p.Title == VirtualContextInitializer.MsfProjectTitle);
                var actual = root.AllMilestones(context).ToArray();
                var expected = expectedTitles.ToArray();
                Array.Sort(actual, (m1, m2) => string.CompareOrdinal(m1.Title, m2.Title));
                Array.Sort(expected, (m1, m2) => string.CompareOrdinal(m1, m2));

                Assert.AreEqual(expected.Length, actual.Length);
                for (int i = 0; i < expected.Length; ++i)
                {
                    Assert.AreEqual(expected[i], actual[i].Title);
                }
            }
        }

        [TestMethod]
        public void GetBelongingProjectBasicTest()
        {
            using (var impl = new VoweiContextImpl())
            {
                var context = new VoweiContext(impl);
                var expected = GetDefaultProject(impl);
                var tasks = expected.AllTickets(context).OfType<Task>();
                var task = tasks.First();

                var actual = task.GetBelongingProject(context);
                Assert.IsTrue(expected.ID == actual.ID);
            }
        }
    }
}
